package com.xxl.sso.server.controller;

import com.xxl.sso.core.conf.Conf;
import com.xxl.sso.core.login.SsoWebLoginHelper;
import com.xxl.sso.core.store.SsoSessionIdHelper;
import com.xxl.sso.core.user.XxlSsoUser;
import com.xxl.sso.server.config.XxlSsoCacheConfig;
import com.xxl.sso.server.core.model.UserInfo;
import com.xxl.sso.server.core.result.ReturnT;
import com.xxl.sso.server.service.UserService;
import feign.Param;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.UUID;

/**
 * sso server (for web)
 *
 * @author xuxueli 2017-08-01 21:39:47
 */
@Controller
@Slf4j
public class ProxyController {

    public static final String TO_URL = "to_url";
    @Autowired
    private UserService userService;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${spring.freemarker.login-page.title:统一用户中心}")
    private String loginPageTitle;

    @Value("${spring.freemarker.login-page.login-logo:统一用户中心}")
    private String loginPageLoginLogo;

    @Value("${spring.freemarker.login-page.login-box-msg:统一用户中心}")
    private String loginPageLoginBoxMsg;


    @Value("${spring.freemarker.index-page.title:统一用户中心}")
    private String indexPageTitle;

    @Value("${spring.freemarker.index-page.h4:统一用户中心}")
    private String indexPageH4;

    @Value("${proxy.proxyUrl}")
    private String PROXY_URL;

    @Value("${proxy.proxyPath}")
    private String PROXY_PATH;

    @Value("${proxy.tokenLoginPath}")
    private String TOKEN_LOGIN_PATH;

    @RequestMapping("/proxy/{thirdPartyCode}")
    public String proxy(@PathVariable("thirdPartyCode") String thirdPartyCode,
                          @Param("receive_url") String receive_url,
                          @Param("to_url") String to_url,
                          HttpServletRequest request,
                          HttpServletResponse response
                          ) {
        log.info("ProxyController receive_url:{}",receive_url);
        log.info("ProxyController to_url:{}",to_url);

        return "redirect:"+PROXY_URL+PROXY_PATH+"/"+thirdPartyCode
                +"?receive_url="+receive_url+"&to_url="+to_url;

    }

    @RequestMapping("/doLoginByToken")
    public String doLoginByToken(HttpServletRequest request,
                                 HttpServletResponse response,
                                 RedirectAttributes redirectAttributes) {

        log.info("ProxyController doLoginByToken executed");
        String token = request.getParameter("sso-proxy-token");
        log.info("ProxyController doLoginByToken token:{}",token);
        //PROXY_URL:http://127.0.0.1:8090
        //TOKEN_LOGIN_PATH:/usercenter-sso-proxy/restapi/getBasicUserInfoByToken
        String requestUrl=PROXY_URL+TOKEN_LOGIN_PATH+"?sso-proxy-token="+token;
        log.info("ProxyController doLoginByToken requestUrl:{}",requestUrl);
        if(ObjectUtils.isEmpty(restTemplate)){
            log.error("ProxyController doLoginByToken restTemplate is null");
            return null;
        }
        HashMap<String,String> resMap =restTemplate.getForObject(requestUrl, HashMap.class);
        log.info("ProxyController doLoginByToken resMap:{}",resMap.toString());
        if(ObjectUtils.isEmpty(resMap)){
            log.error("ProxyController doLoginByToken resMap is null");
            return null;
        }

        String employeeCode = resMap.get("employeeCode");
        log.info("ProxyController doLoginByToken employeeCode:{}",employeeCode);
        String receiveUrl = resMap.get("receiveUrl");
        log.info("ProxyController doLoginByToken receiveUrl:{}",receiveUrl);
        String toUrl = resMap.get("toUrl");
        log.info("ProxyController doLoginByToken toUrl:{}",toUrl);

        if (employeeCode == null || "".equals(employeeCode)) {
            log.error("ProxyController doLoginByToken employeeCode(iscUserSourceId) is null");
            redirectAttributes.addAttribute("errorMsg", "getBasicUserInfo failure");
            redirectAttributes.addAttribute(TO_URL, request.getParameter(TO_URL));
            redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
            log.error("ProxyController doLoginByToken getBasicUserInfo failure");
            return "redirect:/login";
        }
        //根据工号获取用户信息
        ReturnT<UserInfo> userServiceResult = userService.findUserByEmployeeCode(employeeCode);
        if(ObjectUtils.isEmpty(userServiceResult) || userServiceResult.getCode() != 200){
            log.error("ProxyController doLoginByToken can not find user by employeeCode:{}",employeeCode);
            return "redirect:/login";
        }
        UserInfo userInfo = userServiceResult.getData();

        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        xxlUser.setUserid(((null == userInfo.getUserid())?"":String.valueOf(userInfo.getUserid())));
        xxlUser.setUsername(userInfo.getUsername());
        xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
        xxlUser.setUserCode(userInfo.getUserCode());
        xxlUser.setEmployeeId(userInfo.getEmployeeId());
        //xxlUser.setExpireMinute(SsoLoginStore.getExpireMinute());
        xxlUser.setExpireMinute(XxlSsoCacheConfig.getCacheExpireMinute());
        xxlUser.setExpireFreshTime(System.currentTimeMillis());

        // 2、make session id
        String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);
        log.info("ProxyController doLoginByToken sessionId:{}",sessionId);

        // 3、login, store storeKey + cookie sessionId
        SsoWebLoginHelper.login(request,response, sessionId, xxlUser, false);

        log.info("ProxyController doLoginByToken login success, sessionId:{}",sessionId);

        if (receiveUrl != null && receiveUrl.trim().length() > 0) {
            String redirectUrlFinal = receiveUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
            if (!StringUtils.isEmpty(toUrl)) {
                redirectUrlFinal = redirectUrlFinal + "&" + TO_URL + "=" + toUrl;
            }
            log.info("ProxyController doLoginByToken redirectUrl:{}",("redirect:" + redirectUrlFinal));
            return "redirect:" + redirectUrlFinal;
        } else {
            return "redirect:/";
        }
    }

}
